package com.neusoft.bizcore.schedule.config;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.quartz.SchedulerFactoryBeanCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import lombok.extern.slf4j.Slf4j;

/**
 * 自动判断quartz是否需要执行初始化脚本
 *
 * @author sunchf
 * @date 2018年12月26日 下午2:16:03
 */
@Slf4j
@Configuration
@ComponentScan(basePackages = "com.neusoft.bizcore.schedule")
public class BizcoreScheduleConfiguration implements SchedulerFactoryBeanCustomizer {

    @Value("${spring.datasource.driver-class-name}")
    private String dataSourceDriver;

    @Bean(name = "quartzDbInitializer")
    public DataSourceInitializer buildQuartzDataSourceInitializer(DataSource dataSource) {
        final DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();

        dataSourceInitializer.setDataSource(dataSource);

        final ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
        resourceDatabasePopulator.setContinueOnError(true);
        resourceDatabasePopulator.setIgnoreFailedDrops(true);
        resourceDatabasePopulator.setSqlScriptEncoding("UTF-8");
        resourceDatabasePopulator.setScripts(
                new org.springframework.core.io.Resource[] {new ClassPathResource(this.getSqlScriptPath()) });
        dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
        dataSourceInitializer.setEnabled(false);
        Statement stmt = null;
        try {
            final Connection conn = dataSource.getConnection();
            stmt = conn.createStatement();
            stmt.executeQuery("SELECT count(*) FROM QRTZ_JOB_DETAILS");
        } catch (final SQLException e) {
            dataSourceInitializer.setEnabled(true);
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (final SQLException e) {
                    BizcoreScheduleConfiguration.log.error(e.getMessage(), e);
                }
            }
        }

        return dataSourceInitializer;
    }

    private String getSqlScriptPath() {
        String sqlScriptPath = "quartz/tables_postgres.sql";
        if (this.dataSourceDriver.equals("org.h2.Driver")) {
            sqlScriptPath = "quartz/tables_h2.sql";
        } else if (this.dataSourceDriver.equals("com.ibm.db2.jcc.DB2Driver")) {
            sqlScriptPath = "quartz/tables_db2.sql";
        } else if (this.dataSourceDriver.equals("com.mysql.jdbc.Driver")) {
            sqlScriptPath = "quartz/tables_mysql_innodb.sql";
        } else if (this.dataSourceDriver.equals("org.postgresql.Driver")) {
            sqlScriptPath = "quartz/tables_postgres.sql";
        } else if (this.dataSourceDriver.equals("dm.jdbc.driver.DmDriver")) {
            sqlScriptPath = "quartz/tables_oracle.sql";
        }
        return sqlScriptPath;
    }

    @Bean
    public OpenEntityManagerJobListener openEntityManagerJobListener() {
        return new OpenEntityManagerJobListener();
    }

    @Override
    public void customize(SchedulerFactoryBean schedulerFactoryBean) {
        schedulerFactoryBean.setGlobalJobListeners(this.openEntityManagerJobListener());
    }

}
